home *** CD-ROM | disk | FTP | other *** search
/ Enter 2003: The Beautiful Scenery / enter-parhaat-2003.iso / files / frendz.exe / frendz.dcr / Scripts_50_Computer AI.ls < prev    next >
Encoding:
Text File  |  2002-12-31  |  12.4 KB  |  431 lines

  1. global NUM_ROWS, NUM_COLS, NUM_SQUARES, THE_TEMPO, gpvPossibleMovesList, gpvMainBoard, gopvDrawBoards, MIN_COMPUTER_PLAY_TIME, MAX_COMPUTER_LOOK_AHEAD, DEFINITIVE_SQUARE_MULT, INTERIOR_SQUARE_MULT, UNDEF_VALUE, gpvComputerPlayer, gpvEarliestComputerDecide, gpvComputerMove, gpvComputerScores, gpvComputerMoves, gpvComputerMoveIndex, gpvCompBoards, gpvCompPlayerNum, gopvNextResetLevel, gpvBoardValues, gopvBestScore, gopvBestMoves, gpvBestWorstFlags, gpvThrowGame
  2.  
  3. on gopvSetComputerDifficulty computerDiff, numLevel
  4.   gpvThrowGame = 0
  5.   if computerDiff = #easy then
  6.     MAX_COMPUTER_LOOK_AHEAD = 2
  7.     gpvThrowGame = 1
  8.   else
  9.     if computerDiff = #medium then
  10.       MAX_COMPUTER_LOOK_AHEAD = 1
  11.     else
  12.       if computerDiff = #hard then
  13.         MAX_COMPUTER_LOOK_AHEAD = 2
  14.       else
  15.         if computerDiff = #harder then
  16.           MAX_COMPUTER_LOOK_AHEAD = 3
  17.         else
  18.           if computerDiff = #hardest then
  19.             MAX_COMPUTER_LOOK_AHEAD = 4
  20.           else
  21.             alert("Error. computerDiff value" && computerDiff && "is unacceptable")
  22.           end if
  23.         end if
  24.       end if
  25.     end if
  26.   end if
  27. end
  28.  
  29. on goSetMinComputerTime numTicks
  30.   MIN_COMPUTER_PLAY_TIME = numTicks
  31. end
  32.  
  33. on gopvInitComputerPlayer computerDiff, numLevel
  34.   MIN_COMPUTER_PLAY_TIME = 5
  35.   THE_TEMPO = 20
  36.   DEFINITIVE_SQUARE_MULT = 8
  37.   INTERIOR_SQUARE_MULT = 3
  38.   UNDEF_VALUE = 1000000
  39.   gopvSetComputerDifficulty(computerDiff, numLevel)
  40.   gopvDrawBoards = 0
  41.   gpvBoardValues = []
  42.   repeat with i = 1 to NUM_SQUARES
  43.     gpvBoardValues[i] = 0
  44.   end repeat
  45.   gopvInitBoards()
  46. end
  47.  
  48. on goStartComputerMove playerNum
  49.   gpvComputerPlayer = playerNum
  50.   gpvEarliestComputerDecide = the timer + MIN_COMPUTER_PLAY_TIME
  51.   gpvComputerMove = 0
  52.   gopvNextResetLevel = 0
  53.   gpvComputerMoves = []
  54.   gpvComputerScores = []
  55.   gpvComputerMoveIndex = []
  56.   gpvCompBoards = []
  57.   gpvCompPlayerNum = []
  58.   gpvBestWorstFlags = []
  59.   repeat with i = 1 to MAX_COMPUTER_LOOK_AHEAD
  60.     if (i mod 2) = 1 then
  61.       pnum = gpvComputerPlayer
  62.     else
  63.       pnum = 3 - gpvComputerPlayer
  64.     end if
  65.     append(gpvComputerMoves, [])
  66.     append(gpvComputerScores, [])
  67.     append(gpvCompBoards, [])
  68.     gopvInitBoard(gpvCompBoards[i])
  69.     append(gpvComputerMoveIndex, -1)
  70.     append(gpvCompPlayerNum, pnum)
  71.     append(gpvBestWorstFlags, (i = 1) and (gpvThrowGame = 0))
  72.   end repeat
  73. end
  74.  
  75. on gopvMakeNewBoard theCurBoard, theNewBoard, playerNum, pieceNum, drawBoard
  76.   gopvCopyBoard(theCurBoard, theNewBoard)
  77.   if pieceNum <> -1 then
  78.     gopvAssignBoard(theNewBoard, pieceNum, playerNum)
  79.     gopvTransitionBoardEx(theNewBoard, pieceNum)
  80.   end if
  81.   if drawBoard then
  82.     gopvDrawBoard(theNewBoard, pieceNum)
  83.   end if
  84. end
  85.  
  86. on gopvGetNextLevelToDefine
  87.   curLevel = -1
  88.   numPasses = 0
  89.   repeat with i = 1 to MAX_COMPUTER_LOOK_AHEAD
  90.     if gpvComputerMoveIndex[i] = -1 then
  91.       curLevel = i
  92.       exit repeat
  93.       next repeat
  94.     end if
  95.     theMove = gpvComputerMoves[i][gpvComputerMoveIndex[i]]
  96.     if theMove = -1 then
  97.       numPasses = numPasses + 1
  98.       if numPasses = 2 then
  99.         exit repeat
  100.       end if
  101.       next repeat
  102.     end if
  103.     numPasses = 0
  104.   end repeat
  105.   return curLevel
  106. end
  107.  
  108. on drawPathAndScore n, markNum, count1, count2, theScore
  109.   pathStr = EMPTY
  110.   repeat with i = 1 to n
  111.     moveIndex = gpvComputerMoveIndex[i]
  112.     if i = markNum then
  113.       pathStr = pathStr & "*" & moveIndex
  114.       next repeat
  115.     end if
  116.     pathStr = pathStr && moveIndex
  117.   end repeat
  118. end
  119.  
  120. on gopvGetBoardValues theBoard
  121.   repeat with i = 1 to NUM_SQUARES
  122.     if theBoard[i] = 0 then
  123.       gpvBoardValues[i] = 0
  124.       next repeat
  125.     end if
  126.     gpvBoardValues[i] = (2 * theBoard[i]) - 3
  127.   end repeat
  128.   numChanges = 1
  129.   repeat while numChanges > 0
  130.     numChanges = 0
  131.     repeat with row = 1 to NUM_ROWS
  132.       repeat with col = 1 to NUM_COLS
  133.         n = gopvRowColToNum(row, col)
  134.         theValue = gpvBoardValues[n]
  135.         if abs(theValue) = 1 then
  136.           defVert = 0
  137.           defHorz = 0
  138.           defDiag1 = 0
  139.           defDiag2 = 0
  140.           if row = 1 then
  141.             defVert = 1
  142.           else
  143.             if gpvBoardValues[n - NUM_COLS] = (theValue * DEFINITIVE_SQUARE_MULT) then
  144.               defVert = 1
  145.             end if
  146.           end if
  147.           if row = NUM_ROWS then
  148.             defVert = 1
  149.           else
  150.             if gpvBoardValues[n + NUM_COLS] = (theValue * DEFINITIVE_SQUARE_MULT) then
  151.               defVert = 1
  152.             end if
  153.           end if
  154.           if col = 1 then
  155.             defHorz = 1
  156.           else
  157.             if gpvBoardValues[n - 1] = (theValue * DEFINITIVE_SQUARE_MULT) then
  158.               defHorz = 1
  159.             end if
  160.           end if
  161.           if col = NUM_COLS then
  162.             defHorz = 1
  163.           else
  164.             if gpvBoardValues[n + 1] = (theValue * DEFINITIVE_SQUARE_MULT) then
  165.               defHorz = 1
  166.             end if
  167.           end if
  168.           if (row = 1) or (col = 1) then
  169.             defDiag1 = 1
  170.           else
  171.             if gpvBoardValues[n - NUM_COLS - 1] = (theValue * DEFINITIVE_SQUARE_MULT) then
  172.               defDiag1 = 1
  173.             end if
  174.           end if
  175.           if (row = NUM_ROWS) or (col = NUM_COLS) then
  176.             defDiag1 = 1
  177.           else
  178.             if gpvBoardValues[n + NUM_COLS + 1] = (theValue * DEFINITIVE_SQUARE_MULT) then
  179.               defDiag1 = 1
  180.             end if
  181.           end if
  182.           if (row = 1) or (col = NUM_COLS) then
  183.             defDiag2 = 1
  184.           else
  185.             if gpvBoardValues[n - NUM_COLS + 1] = (theValue * DEFINITIVE_SQUARE_MULT) then
  186.               defDiag2 = 1
  187.             end if
  188.           end if
  189.           if (row = NUM_ROWS) or (col = 1) then
  190.             defDiag2 = 1
  191.           else
  192.             if gpvBoardValues[n + NUM_COLS - 1] = (theValue * DEFINITIVE_SQUARE_MULT) then
  193.               defDiag2 = 1
  194.             end if
  195.           end if
  196.           if defVert and defHorz and defDiag1 and defDiag2 then
  197.             gpvBoardValues[n] = gpvBoardValues[n] * DEFINITIVE_SQUARE_MULT
  198.             numChanges = numChanges + 1
  199.           end if
  200.         end if
  201.       end repeat
  202.     end repeat
  203.   end repeat
  204.   n = gopvRowColToNum(1, 1)
  205.   gpvBoardValues[n] = 2 * gpvBoardValues[n]
  206.   n = gopvRowColToNum(NUM_ROWS, 1)
  207.   gpvBoardValues[n] = 2 * gpvBoardValues[n]
  208.   n = gopvRowColToNum(1, NUM_COLS)
  209.   gpvBoardValues[n] = 2 * gpvBoardValues[n]
  210.   n = gopvRowColToNum(NUM_ROWS, NUM_COLS)
  211.   gpvBoardValues[n] = 2 * gpvBoardValues[n]
  212. end
  213.  
  214. on gopvCheckPrune theLevel, leafNode
  215.   if theLevel > 1 then
  216.     doPrune = 0
  217.     theMoveIndex = gpvComputerMoveIndex[theLevel]
  218.     theScore = gpvComputerScores[theLevel][theMoveIndex]
  219.     if gpvBestWorstFlags[theLevel] = 1 then
  220.       betaValue = gpvComputerScores[theLevel - 1].min()
  221.       if theScore > betaValue then
  222.         doPrune = 1
  223.       end if
  224.     else
  225.       alphaValue = gpvComputerScores[theLevel - 1].max()
  226.       if theScore < alphaValue then
  227.         doPrune = 1
  228.       end if
  229.     end if
  230.     if doPrune then
  231.       if leafNode = 0 then
  232.         xxxxxx = 1
  233.       end if
  234.       gpvComputerMoveIndex[theLevel] = gpvComputerMoves[theLevel].count()
  235.       repeat with i = theLevel + 1 to MAX_COMPUTER_LOOK_AHEAD
  236.         gpvComputerMoveIndex[i] = -1
  237.         gpvComputerMoves[i] = []
  238.       end repeat
  239.     end if
  240.   end if
  241. end
  242.  
  243. on gopvGetPathAndScore playerNum, drawResults
  244.   repeat with i = 1 to MAX_COMPUTER_LOOK_AHEAD
  245.     moveIndex = gpvComputerMoveIndex[i]
  246.     if moveIndex = -1 then
  247.       n = i - 1
  248.       exit repeat
  249.     end if
  250.     n = i
  251.   end repeat
  252.   theCounts = [0, 0]
  253.   theBoard = gpvCompBoards[n]
  254.   gopvGetBoardValues(theBoard)
  255.   repeat with i = 1 to NUM_SQUARES
  256.     pieceNum = theBoard[i]
  257.     if pieceNum > 0 then
  258.       theCounts[pieceNum] = theCounts[pieceNum] + abs(gpvBoardValues[i])
  259.     end if
  260.   end repeat
  261.   if playerNum = 1 then
  262.     theScore = theCounts[1] - theCounts[2]
  263.   else
  264.     theScore = theCounts[2] - theCounts[1]
  265.   end if
  266.   gpvComputerScores[n][gpvComputerMoveIndex[n]] = theScore
  267.   gopvCheckPrune(n, 1)
  268.   if gopvDrawBoards then
  269.     drawPathAndScore(n, gopvNextResetLevel, theCounts[1], theCounts[2], theScore)
  270.     repeat with i = n down to 1
  271.     end repeat
  272.   end if
  273. end
  274.  
  275. on gopvRecurseOneMove
  276.   curLevel = gopvGetNextLevelToDefine()
  277.   repeat while curLevel <> -1
  278.     gpvComputerMoves[curLevel] = []
  279.     gpvComputerScores[curLevel] = []
  280.     if curLevel = 1 then
  281.       theCurBoard = gpvMainBoard
  282.     else
  283.       theCurBoard = gpvCompBoards[curLevel - 1]
  284.     end if
  285.     numMoves = gopvNewNumPossibleMoves(gpvCompPlayerNum[curLevel], theCurBoard, gpvComputerMoves[curLevel])
  286.     if gpvBestWorstFlags[curLevel] = 1 then
  287.       defScore = -UNDEF_VALUE
  288.     else
  289.       defScore = UNDEF_VALUE
  290.     end if
  291.     if numMoves = 0 then
  292.       append(gpvComputerMoves[curLevel], -1)
  293.       append(gpvComputerScores[curLevel], defScore)
  294.     else
  295.       repeat with i = 1 to numMoves
  296.         append(gpvComputerScores[curLevel], defScore)
  297.       end repeat
  298.     end if
  299.     gpvComputerMoveIndex[curLevel] = 1
  300.     if gopvDrawBoards then
  301.       put "Level" && curLevel && "Defined for Player" && gpvCompPlayerNum[curLevel] && ": " && gpvComputerMoves[curLevel]
  302.     end if
  303.     theMove = gpvComputerMoves[curLevel][1]
  304.     gopvMakeNewBoard(theCurBoard, gpvCompBoards[curLevel], gpvCompPlayerNum[curLevel], theMove, gopvDrawBoards)
  305.     curLevel = gopvGetNextLevelToDefine()
  306.   end repeat
  307.   gopvGetPathAndScore(gpvCompPlayerNum[1], 1)
  308. end
  309.  
  310. on gopvChooseScore curLevel, scoresList
  311.   perspectivePlayerNum = gpvCompPlayerNum[1]
  312.   thisPlayerNum = gpvCompPlayerNum[curLevel]
  313.   if thisPlayerNum = perspectivePlayerNum then
  314.     theScore = scoresList.max()
  315.   else
  316.     theScore = scoresList.min()
  317.   end if
  318.   return theScore
  319. end
  320.  
  321. on gopvNextMove
  322.   if gopvDrawBoards then
  323.     put "*********** Finding next Move ***********"
  324.   end if
  325.   retcode = 0
  326.   repeat with i = MAX_COMPUTER_LOOK_AHEAD down to 0
  327.     if gpvComputerMoveIndex[i] <> -1 then
  328.       curLevel = i
  329.       exit repeat
  330.     end if
  331.   end repeat
  332.   repeat while (curLevel > 0) and (retcode = 0)
  333.     moveIndex = gpvComputerMoveIndex[curLevel] + 1
  334.     if moveIndex <= count(gpvComputerMoves[curLevel]) then
  335.       gpvComputerMoveIndex[curLevel] = moveIndex
  336.       theMove = gpvComputerMoves[curLevel][moveIndex]
  337.       if curLevel = 1 then
  338.         theCurBoard = gpvMainBoard
  339.       else
  340.         theCurBoard = gpvCompBoards[curLevel - 1]
  341.       end if
  342.       if gopvDrawBoards then
  343.         put "NextMove is at Level" && curLevel && ", Index" && moveIndex && ", Move" && theMove
  344.       end if
  345.       gopvMakeNewBoard(theCurBoard, gpvCompBoards[curLevel], gpvCompPlayerNum[curLevel], theMove, gopvDrawBoards)
  346.       gopvNextResetLevel = curLevel
  347.       retcode = 1
  348.       next repeat
  349.     end if
  350.     if gopvDrawBoards then
  351.       put "No more Moves at Level" && curLevel && "so reseting to undefined and backing up"
  352.     end if
  353.     if curLevel > 1 then
  354.       if gpvBestWorstFlags[curLevel] = 1 then
  355.         chosenScore = gpvComputerScores[curLevel].max()
  356.       else
  357.         chosenScore = gpvComputerScores[curLevel].min()
  358.       end if
  359.       curMoveIndex = gpvComputerMoveIndex[curLevel - 1]
  360.       gpvComputerScores[curLevel - 1][curMoveIndex] = chosenScore
  361.       gopvCheckPrune(curLevel - 1, 0)
  362.     end if
  363.     gpvComputerMoveIndex[curLevel] = -1
  364.     curLevel = curLevel - 1
  365.   end repeat
  366.   return retcode
  367. end
  368.  
  369. on gopvNewBestMove
  370.   gopvBestMoves = []
  371.   if gpvThrowGame = 0 then
  372.     gopvBestScore = -UNDEF_VALUE
  373.   else
  374.     gopvBestScore = UNDEF_VALUE
  375.   end if
  376.   theMoveList = gpvComputerMoves[1]
  377.   theScoreList = gpvComputerScores[1]
  378.   n = count(theScoreList)
  379.   repeat with i = 1 to n
  380.     theMove = theMoveList[i]
  381.     theScore = theScoreList[i]
  382.     if theScore = gopvBestScore then
  383.       append(gopvBestMoves, theMove)
  384.       next repeat
  385.     end if
  386.     if gpvThrowGame = 0 then
  387.       if theScore > gopvBestScore then
  388.         gopvBestScore = theScore
  389.         gopvBestMoves = [theMove]
  390.       end if
  391.       next repeat
  392.     end if
  393.     if theScore < gopvBestScore then
  394.       gopvBestScore = theScore
  395.       gopvBestMoves = [theMove]
  396.     end if
  397.   end repeat
  398. end
  399.  
  400. on gopvRecurseComputerMoves timeToQuit
  401.   moreMoves = 1
  402.   repeat while (moreMoves = 1) and (the timer <= timeToQuit)
  403.     gopvRecurseOneMove()
  404.     moreMoves = gopvNextMove()
  405.   end repeat
  406.   theMove = 0
  407.   if moreMoves = 0 then
  408.     gopvNewBestMove()
  409.     numMoves = count(gopvBestMoves)
  410.     if numMoves > 0 then
  411.       whichMove = random(count(gopvBestMoves))
  412.       theMove = gopvBestMoves[whichMove]
  413.     else
  414.       theMove = -1
  415.     end if
  416.   end if
  417.   return theMove
  418. end
  419.  
  420. on goContinueComputerMove
  421.   if gpvComputerMove = 0 then
  422.     gpvComputerMove = gopvRecurseComputerMoves(the timer + (60 / THE_TEMPO))
  423.   end if
  424.   if the timer >= gpvEarliestComputerDecide then
  425.     retcode = gpvComputerMove
  426.   else
  427.     retcode = 0
  428.   end if
  429.   return retcode
  430. end
  431.